package com.honey.compilation.sql;

import java.sql.Types;

import com.honey.core.builder.CharacterBuilder;
import com.honey.core.builder.CharacterBuilderFactory;
import com.honey.core.compiler.CompilationException;
import com.honey.core.compiler.IndentSpace;
import com.honey.core.utils.StringUtility;


/**
 * 
 * SQL 92 中关于 column的定义 <br />
 * &lt;column definition&gt;    ::= <br />
 * &lt;column name> { &lt;data type&gt; | &lt;domain name&gt; } [ &lt;default clause&gt; ] [ &lt;column constraint definition&gt; ... ] [ &lt;collate clause&gt; ] <br />
 * 
 * 注意:<br />
 * 	default clause 放在了约束里面
 * 
 * @author Administrator
 *
 */
public class SqlColumn extends SqlElement {
	
	/** 数据库类型 */
	private SqlType sqlType;
	
	/** 字段名称 */
	private ValueElement name;
	
	/** 数据库comment */
	private String comment;

	/**
	 * 构造函数
	 * @param name 字段名称
	 * @param jdbcType 在java.sql.Types类中指定类型
	 */
	public SqlColumn(String name ) {
		this(name,Types.INTEGER);
	}
	
	/**
	 * 构造函数
	 * @param name 字段名称
	 * @param jdbcType 在java.sql.Types类中指定类型
	 */
	public SqlColumn(String name , int jdbcType ) {
		this(name,new SqlType(jdbcType));
	}
	
	/**
	 * 构造函数
	 * @param name 字段名称
	 * @param jdbcType 在java.sql.Types类中指定类型
	 * @param length 字段长度,SQL 92中只有部分(例如DECIMAL,NUMERIC )定义长度,其它都没有定义长度
	 */
	public SqlColumn(String name , int jdbcType,int length ) {
		this(name,new SqlType(jdbcType,length));
	}
	
	/**
	 * 构造函数
	 * @param name 字段名称
	 * @param jdbcType 在java.sql.Types类中指定类型
	 * @param length 字段长度,SQL 92中只有部分(例如DECIMAL,NUMERIC )定义长度,其它都没有定义长度
	 * @param scale 小数位
	 */
	public SqlColumn(String name , int jdbcType,int length,int scale ) {
		this(name,new SqlType(jdbcType,length,scale,false));
	}
	
	/**
	 * 构造函数
	 * @param name 字段名称  
	 * @param sqlType 数据类型对象
	 */
	public SqlColumn(String name , SqlType sqlType) {
		this.name = new ValueElement(name);
		this.sqlType = sqlType ;
	}
	
	public ValueElement getName() {
		return name;
	}

	/**
	 * 数据库中的comment
	 * @return
	 */
	public String getComment() {
		return comment;
	}
	
	/**
	 * 数据库中的comment
	 * @param comment
	 */
	public SqlColumn setComment(String comment) {
		this.comment = comment;
		return this;
	}
	
	/**
	 * 获取数据类型
	 * @return
	 */
	public SqlType getSqlType() {
		return sqlType;
	}

	/**
	 * 设定数据库类型
	 * @param sqlType
	 */
	public void setSqlType(SqlType sqlType) {
		this.sqlType = sqlType;
	}
	
	/**
	 * 判断当前的列是否是数字类型的列
	 * @return
	 */
	public boolean isNumber(){
		int jdbcType =this.getSqlType(). getJdbctype();
		return jdbcType== Types.BIGINT||
			   jdbcType== Types.INTEGER||
			   jdbcType== Types.DOUBLE||
			   jdbcType== Types.FLOAT||
			   jdbcType== Types.TINYINT||
			   jdbcType== Types.SMALLINT||
			   jdbcType== Types.DECIMAL||
			   jdbcType== Types.NUMERIC||
			   jdbcType== Types.REAL
			   ;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.honey.core.dom.CompilationElement#compiledContent(int)
	 */
	@Override
	public CharacterBuilder compiledContent(int indentLevel) throws CompilationException {
		int linelength=50;
		CharacterBuilder answer = CharacterBuilderFactory.createC64StringBuilder();
		IndentSpace.newLine(answer);
		IndentSpace.spaceIndent(answer, indentLevel);
		addFormattedSqlDocLines(answer, indentLevel);
		answer.append( formatName (getName().compiledContent(0),10 ));
		if(getSqlType() != null){
			answer.append(getSqlType().compiledContent(0));
		}
		
		//comment , SQL 92中没有定义
		if(StringUtility.stringHasValue(getComment())){
			String []l= answer.toString().split("\n");
			int linesize =l[ l.length -1 ].length();
			if(linesize < linelength){
				IndentSpace.space(answer, linelength - linesize);
			}
			answer.append(SqlKeyWord.COMMENT).append(SqlKeyWord.OPERATION_SINGLE_QUOTES).append(getComment()).append(SqlKeyWord.OPERATION_SINGLE_QUOTES);
		}

		return answer;
	}
	
	/**
	 * 格式化列的名称
	 * @param str
	 * @param length
	 * @return
	 */
	protected String formatName(CharacterBuilder str ,int length){
		CharacterBuilder answer = CharacterBuilderFactory.createC16StringBuilder();
		answer.append(str);
		int i=str.length();
		if(i < length ){
			for(int ii=0 , size=length-i ; ii < size ; ii++ )
				answer.append(" ");
		
		}
		return answer.toString();
	}
	
	
	/**
	 * 数据库的列名是不能重复的,所以只要列名相等就是同一个列.
	 */
	@Override
	public boolean equals(Object obj) {
		if( obj instanceof SqlColumn ){
			SqlColumn column =(SqlColumn)obj;
			boolean b =this.getName().equals(column.getName()); 
			return b;
		}else{
			return false;
		}
	}

	/**
	 * 数据库的列名是不能重复的,所以只要列名相等就是同一个列.
	 */
	@Override
	public int hashCode() {
		return getName().hashCode();
		
	}
}
